import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.Field;
public class GCUtil extends Thread {
	static Object Reflock;
	static Object Finlock;
	static Thread Reference;
	static Thread Finalizer;
	long mills;
	static {
		try {
			ThreadGroup groups = Thread.currentThread().getThreadGroup().getParent();
			Thread[] threads = new Thread[groups.activeCount()];
			groups.enumerate(threads);
			for (Thread t : threads) {
				if (t.getName().equals("Reference Handler")) {
					Reference = t;
				} else if (t.getName().equals("Finalizer")) {
					Finalizer = t;
				}
			}
			Field ref = Reference.class.getDeclaredField("lock");
			ref.setAccessible(true);
			Reflock = ref.get(Reference.class);
			Field fin = ReferenceQueue.class.getDeclaredField("lock");
			fin.setAccessible(true);
			Finlock = ref.get(Finalizer);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void run() {
		synchronized (Reflock) {
			try {
				System.out.println("locked");
				Reflock.wait();
				System.out.println("notifyed");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	public static void startGC() {
		synchronized (Reflock) {
			Reflock.notifyAll();
		}
		synchronized (Finlock) {
			Finlock.notifyAll();
		}
	}
	public synchronized static void holdGC(long mills) {
		GCUtil gc = new GCUtil();
		gc.mills = mills;
		gc.setDaemon(true);
		gc.start();
	}
	public static void main(String args[]) throws Exception {
		holdGC(5000);
		ThreadMXBean tmxbean = ManagementFactory.getThreadMXBean();
		ThreadGroup groups = Thread.currentThread().getThreadGroup().getParent();
		Thread[] threads = new Thread[groups.activeCount()];
		groups.enumerate(threads);
		Field blockerLock = Thread.class.getDeclaredField("blockerLock");
		blockerLock.setAccessible(true);
		for (Thread t : threads) {
			System.out.println(t.getName() + " " + t.getState().name());
			Object lock = blockerLock.get(t);
			synchronized (lock) {
				lock.notifyAll();
			}
			// startGC();
			ThreadInfo tinfo = tmxbean.getThreadInfo(t.getId());
			System.out.println("lock:" + tinfo.getLockName());
			
			System.out.println(t.getName() + " " + t.getState().name());
			StackTraceElement[] eles = t.getStackTrace();
			for (StackTraceElement e : eles) {
				System.out.println("\t" + e.getClassName() + " " + e.getMethodName());
			}
		}
		
	}
}
